﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Input;

namespace AppToolkit.WPF.Services.UserMessageHandling
{
    /// <summary>
    /// Interface exposed to the application that allows displaying messages to the user.
    /// </summary>
    public interface IMessageService
    {
        /// <summary>
        /// Show the specified <see cref="Message"/> to the user.
        /// </summary>
        /// <param name="msg"></param>
        void ShowMessage(Message msg);
    }

    /// <summary>
    /// Interface exposed to component visualizing user messages.
    /// </summary>
    public interface IMessageVisualizer : INotifyPropertyChanged
    {
        /// <summary>
        /// Collection of previously displayed <see cref="Message"/>s.
        /// </summary>
        ICollectionView MessageHistory { get; }
        
        /// <summary>
        /// True, if <see cref="Message"/> is currently displayed.
        /// </summary>
        bool ShowInfo { get; }

        /// <summary>
        /// Triggers hiding the currenly shown message window.
        /// </summary>
        ICommand HideInfoCommand { get; }

        /// <summary>
        /// True, if message window has currenly the input focus.
        /// </summary>
        bool IsFocused { set; get; }
    }

    /// <summary>
    /// Message to be shown to the user.
    /// </summary>
    public class Message
    {
        /// <summary>
        /// Subject of the message.
        /// </summary>
        public string Subject { get; set; }

        /// <summary>
        /// Detailed description.
        /// </summary>
        public string Details { get; set; }

        /// <summary>
        /// Criticality of the message.
        /// </summary>
        public MessageType Type { get; set; }

        /// <summary>
        /// Optional: exception that caused the message. Attaching an exception automatically promotes the message to
        /// type <see cref="MessageType.Error"/>.
        /// </summary>
        public Exception AttachedException { get; set; }
    }

    /// <summary>
    /// Criticality of a message.
    /// </summary>
    public enum MessageType
    {
        /// <summary>
        /// Only for informal purpose.
        /// </summary>
        Info,
        /// <summary>
        /// Uncritical situation, but may need user attention if situation persists.
        /// </summary>
        Warning,
        /// <summary>
        /// Recoverable error situation, where data might been lost.
        /// </summary>
        Error,
        /// <summary>
        /// Unrecoverable error, application needs to be closed. Data might been lost.
        /// </summary>
        Critical
    }
}
